#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/evp.h>
#include <openssl/err.h>

// PKCS#7填充函数
int pkcs7_pad(const unsigned char *data, size_t data_len, 
              unsigned char **padded_data, size_t *padded_len, 
              size_t block_size) {
    // 验证块大小有效性
    if (block_size < 1 || block_size > 255) {
        fprintf(stderr, "错误: 无效块大小 %zu (必须是1-255)\n", block_size);
        return 0;
    }
    
    // 计算需要填充的字节数
    size_t padding_needed = block_size - (data_len % block_size);
    // 如果数据长度是块大小的倍数，填充整个块
    if (padding_needed == 0) padding_needed = block_size;
    
    // 分配内存：原始数据 + 填充字节
    *padded_len = data_len + padding_needed;
    *padded_data = (unsigned char *)malloc(*padded_len);
    if (!*padded_data) {
        perror("内存分配失败");
        return 0;
    }
    
    // 复制原始数据
    memcpy(*padded_data, data, data_len);
    
    // 添加填充字节
    for (size_t i = 0; i < padding_needed; i++) {
        (*padded_data)[data_len + i] = (unsigned char)padding_needed;
    }
    
    return 1;
}

// PKCS#7解填充函数
int pkcs7_unpad(const unsigned char *padded_data, size_t padded_len, 
                unsigned char **data, size_t *data_len, 
                size_t block_size) {
    // 验证数据长度是块大小的倍数
    if (padded_len == 0 || padded_len % block_size != 0) {
        fprintf(stderr, "错误: 数据长度(%zu)不是块大小(%zu)的倍数\n", 
                padded_len, block_size);
        return 0;
    }
    
    // 获取填充长度
    unsigned char pad_length = padded_data[padded_len - 1];
    
    // 验证填充长度有效性
    if (pad_length < 1 || pad_length > block_size) {
        fprintf(stderr, "错误: 无效填充长度 %u\n", pad_length);
        return 0;
    }
    
    // 验证填充内容是否正确
    size_t padding_start = padded_len - pad_length;
    for (size_t i = padding_start; i < padded_len; i++) {
        if (padded_data[i] != pad_length) {
            fprintf(stderr, "错误: 填充字节无效\n");
            return 0;
        }
    }
    
    // 分配内存并复制原始数据
    *data_len = padding_start;
    *data = (unsigned char *)malloc(*data_len);
    if (!*data) {
        perror("内存分配失败");
        return 0;
    }
    
    memcpy(*data, padded_data, *data_len);
    return 1;
}
